<?php
namespace shenyewangyue\Jt808;
use shenyewangyue\Jt808\Jt808;

class Jt0200{

/*
 * 消息ID：0x0200。
 * 位置信息汇报消息体由位置基本信息和位置附加信息项列表组成，消息结构图如图3所示
 *
 * | 起始字节 | 字段 | 数据类型 | 描述及要求 |
 * |---|---|---|---|---|
 * | 0 | 报警标志 | DWORD | 报警标志位定义见 表 24 |
 * | 4 | 状态 | DWORD | 状态位定义见 表 25 |
 * | 8 | 纬度 | DWORD | 以度为单位的纬度值乘以 10 的 6 次方，精确到百万分之一度 |
 * | 12 | 经度 | DWORD | 以度为单位的经度值乘以 10 的 6 次方，精确到百万分之一度 |
 * | 16 | 高程 | WORD | 海拔高度，单位为米（m） |
 * | 18 | 速度 | WORD | 1/10km/h |
 * | 20 | 方向 | WORD | 0-359，正北为 0，顺时针 |
 * | 21 | 时间 | BCD[6] | YY-MM-DD-hh-mm-ss（GMT+8 时间，本标准中之后涉及的时间均采用此时区） |
*/
    public $mesageBody = [];
    public $jt808;
    public function __construct($data)
    {
        $this->mesageBody = $data;
        $this->jt808 = new Jt808();
    }
    public function getJt0200Data(){
        $mesageBodyArray = [
            'alarm' => $this->getAlarmMessage(),//报警信息
            'alarmArray' => $this->getAlarmMessageArray(),//报警信息
            'positionStatus' => $this->getPositionStatus(),//状态
            'positionStatusArray' => $this->getPositionStatusArray(),//状态
            'latitude' => $this->getLatitude('f'),//经度
            'longitude' => $this->getLongitude('f'),//纬度
            'height' => $this->getHeight(),//高度
            'speed' => $this->getSpeed(),//速度
            'direction' => $this->getDirection(),//方向
            'datetime' => $this->getDatetime(),//时间
        ];
        return $mesageBodyArray;
    }
// | 0 | 报警标志 | DWORD | 报警标志位定义见 表 24 |
    /**
     * description  获取报警信息
     * @return int  返回数字代表报警信息
     */
    public function getAlarmMessage($type = false) {
        $alarmArray = $this->jt808->getTwoStr(array_slice($this->mesageBody, 0, 4));
        if ($type == true) {
            if (substr($alarmArray, -8, 1) == 1) {
                //主电源断电
                $alarm = "主电源断电";
            } elseif (substr($alarmArray, -30, 1) == 1) {
                //碰撞预警
                $alarm = "碰撞预警";
            } elseif (substr($alarmArray, -31, 1) == 1) {
                //侧翻预警
                $alarm = "侧翻预警";
            } else {
                //正常
                $alarm = "一切正常";
            }
            return $alarm;
        }
        return $alarmArray;
    }
    public function getAlarmMessageArray(){
        $alarmArray = $this->getAlarmMessage();
        // 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00
        $alarm['0'] = substr($alarmArray, -1, 1) == 1 ? '紧急报警，触动报警开关后触发' : '';
        $alarm['1'] = substr($alarmArray, -2, 1) == 1 ? '超速报警' : '';
        $alarm['2'] = substr($alarmArray, -3, 1) == 1 ? '疲劳驾驶' : '';
        $alarm['3'] = substr($alarmArray, -4, 1) == 1 ? '危险预警' : '';
        $alarm['4'] = substr($alarmArray, -5, 1) == 1 ? 'GNSS 模块发生故障' : '';
        $alarm['5'] = substr($alarmArray, -6, 1) == 1 ? 'GNSS 天线未接或被剪断' : '';
        $alarm['6'] = substr($alarmArray, -7, 1) == 1 ? 'GNSS 天线短路' : '';
        $alarm['7'] = substr($alarmArray, -8, 1) == 1 ? '终端主电源欠压' : '';
        $alarm['8'] = substr($alarmArray, -9, 1) == 1 ? '终端主电源掉电' : '';
        $alarm['9'] = substr($alarmArray, -10, 1) == 1 ? '终端 LCD 或显示器故障' : '';
        $alarm['10'] = substr($alarmArray, -11, 1) == 1 ? 'TTS 模块故障' : '';
        $alarm['11'] = substr($alarmArray, -12, 1) == 1 ? '摄像头故障' : '';
        $alarm['12'] = substr($alarmArray, -13, 1) == 1 ? '道路运输证 IC 卡模块故障' : '';
        $alarm['13'] = substr($alarmArray, -14, 1) == 1 ? '超速预警' : '';
        $alarm['14'] = substr($alarmArray, -15, 1) == 1 ? '疲劳驾驶预警' : '';
//            $alarm['17'] = substr($alarmArray, -18, 3) == 1 ? '' : '';
        $alarm['18'] = substr($alarmArray, -19, 1) == 1 ? '当天累计驾驶超时' : '';
        $alarm['19'] = substr($alarmArray, -20, 1) == 1 ? '超时停车' : '';
        $alarm['20'] = substr($alarmArray, -21, 1) == 1 ? '进出区域' : '';
        $alarm['21'] = substr($alarmArray, -22, 1) == 1 ? '进出路线' : '';
        $alarm['22'] = substr($alarmArray, -23, 1) == 1 ? '路段行驶时间不足/过长' : '';
        $alarm['23'] = substr($alarmArray, -24, 1) == 1 ? '路线偏离报警' : '';
        $alarm['24'] = substr($alarmArray, -25, 1) == 1 ? '车辆 VSS 故障' : '';
        $alarm['25'] = substr($alarmArray, -26, 1) == 1 ? '车辆油量异常' : '';
        $alarm['26'] = substr($alarmArray, -27, 1) == 1 ? '车辆被盗(通过车辆防盗器)' : '';
        $alarm['27'] = substr($alarmArray, -28, 1) == 1 ? '车辆非法点火' : '';
        $alarm['28'] = substr($alarmArray, -29, 1) == 1 ? '车辆非法位移' : '';
        $alarm['29'] = substr($alarmArray, -30, 1) == 1 ? '碰撞预警' : '';
        $alarm['30'] = substr($alarmArray, -31, 1) == 1 ? '侧翻预警' : '';
        $alarm['31'] = substr($alarmArray, -32, 1) == 1 ? '非法开门报警（终端未设置区域时，不判断非法开门）' : '';
        if($alarm){
            foreach ($alarm as $k=>$v) {
                if(!$v){
                    unset($alarm[$k]);
                }
            }
        }
        return $alarm;
    }
// | 4 | 状态 | DWORD | 状态位定义见 表 25 |

    /**
     * description   获取状态信息
     * @param $type   返回数据还是原本信息
     * @return array  状态信息数组
     */
    public function getPositionStatus($type = false) {
        $positionArray = $this->jt808->getTwoStr(array_slice($this->mesageBody, 4, 4));
        if ($type == true) {
            //判断是否定位，0定位，1未定位
            $isPosition = substr($positionArray, -2, 1) == 0 ? $isPosition = "未定位" : $isPosition = "定位";
            //判断南北纬，0北纬，1南纬
            $isNorSou = substr($positionArray, -3, 1) == 0 ? $isNorSou = "北纬" : $isNorSou = "南纬";
            //判断东西经，0东经，1西经
            $isEasWes = substr($positionArray, -4, 1) == 0 ? $isEasWes = "东经" : $isEasWes = "西经";
            //判断定位方式
            if (substr($positionArray, -19, 1) == 1 && substr($positionArray, -20, 1) == 0) {
                //北斗定位
                $positionMethod = "北斗定位";
            } elseif (substr($positionArray, -19, 1) == 0 && substr($positionArray, -20, 1) == 1) {
                //GPS定位
                $positionMethod = "GPS定位";
            } elseif (substr($positionArray, -19, 1) == 1 && substr($positionArray, -20, 1) == 1) {
                //北斗GPS双定位
                $positionMethod = "北斗GPS双定位";
            } else {
                //北斗GPS都未定位
                $positionMethod = "北斗GPS都未定位";
            }
            $positionStatusArray = array(
                'position' => $isPosition,
                'ns' => $isNorSou,
                'ew' => $isEasWes,
                'gps' => $positionMethod,
            );
            return $positionStatusArray;
        } else {
            return $positionArray;
        }
    }
    public function getPositionStatusArray(){
        $positionArray = $this->getPositionStatus();
        $positionAttr = [];
        // 00000000000000000000000000000010
        //位 状态
        //0 0：ACC 关；1： ACC 开
//            $positionAttr['is_acc'] = substr($positionArray, 31, 1) == 1 ? 'ACC开' : 'ACC关';
        $positionAttr['is_acc'] = substr($positionArray, -1, 1) == 1 ? 'ACC开' : 'ACC关';
        //1 0：未定位；1：定位
//            $positionAttr['is_dingwei'] = substr($positionArray, 30, 1) == 1 ? '定位' : '未定位';
        $positionAttr['is_dingwei'] = substr($positionArray, -2, 1) == 1 ? '定位' : '未定位';
        //2 0：北纬；1：南纬
//            $positionAttr['is_nanbei'] = substr($positionArray, 29, 1) == 1 ? '南纬' : '北纬';
        $positionAttr['is_nanbei'] = substr($positionArray, -3, 1) == 1 ? '南纬' : '北纬';
        //3 0：东经；1：西经
//            $positionAttr['is_dongxi'] = substr($positionArray, 28, 1) == 1 ? '西经' : '东经';
        $positionAttr['is_dongxi'] = substr($positionArray, -4, 1) == 1 ? '西经' : '东经';
        //4 0：运营状态；1：停运状态
//            $positionAttr['is_dongxi'] = substr($positionArray, 27, 1) == 1 ? '停运状态' : '停运状态';
        $positionAttr['is_dongxi'] = substr($positionArray, -5, 1) == 1 ? '停运状态' : '停运状态';
        //5 0：经纬度未经保密插件加密；1：经纬度已经保密插件加密
//            $positionAttr['is_jiami'] = substr($positionArray, 26, 1) == 1 ? '经纬度已经保密插件加密' : '经纬度未经保密插件加密';
        $positionAttr['is_jiami'] = substr($positionArray, -6, 1) == 1 ? '经纬度已经保密插件加密' : '经纬度未经保密插件加密';
        //6-7 保留
//            substr($positionArray, 23, 2);
//            $baoliu = substr($positionArray, -8, 2);
        //8-9 00：空车；01：半载；10：保留；11：满载（可用于客车的空、重车及货车的空载、满载状态表示，人工输入或传感器获取）
//            substr($positionArray, 23, 2);
        $zhzt = substr($positionArray, -10, 2);
        switch ($zhzt){
            case "00":
                $positionAttr['is_jiami'] = '空车';
                break;
            case "01":
                $positionAttr['is_jiami'] = '半载';
                break;
            case "10":
                $positionAttr['is_jiami'] = '保留';
                break;
            case "11":
                $positionAttr['is_jiami'] = '满载（可用于客车的空、重车及货车的空载、满载状态表示，人工输入或传感器获取）';
                break;
            default:
                $positionAttr['is_jiami'] = '其他';
                break;
        }

        //10 0：车辆油路正常；1：车辆油路断开
        $positionAttr['is_you'] = substr($positionArray, -11, 1) == 1 ? '车辆油路断开' : '车辆油路正常';
//            $positionAttr['is_you'] = substr($positionArray, 21, 1) == 1 ? '车辆油路断开' : '车辆油路正常';
        //11 0：车辆电路正常；1：车辆电路断开
        $positionAttr['is_dian'] = substr($positionArray, -12, 1) == 1 ? '车辆电路断开' : '车辆电路正常';
//            $positionAttr['is_dian'] = substr($positionArray, 20, 1) == 1 ? '车辆电路断开' : '车辆电路正常';
        //12 0：车门解锁；1：车门加锁
        $positionAttr['is_chemen'] = substr($positionArray, -13, 1) == 1 ? '车门加锁' : '车门解锁';
//            $positionAttr['is_chemen'] = substr($positionArray, 19, 1) == 1 ? '车门加锁' : '车门解锁';
        //13 0：门 1 关；1：门 1 开（前门）
        $positionAttr['is_men1'] = substr($positionArray, -14, 1) == 1 ? '门 1 开（前门）' : '门 1 关';
//            $positionAttr['is_men1'] = substr($positionArray, 18, 1) == 1 ? '门 1 开（前门）' : '门 1 关';
        //14 0：门 2 关；1：门 2 开（中门）
        $positionAttr['is_men2'] = substr($positionArray, -15, 1) == 1 ? '门 2 开（中门）' : '门 2 关';
//            $positionAttr['is_men2'] = substr($positionArray, 17, 1) == 1 ? '门 2 开（中门）' : '门 2 关';
        //15 0：门 3 关；1：门 3 开（后门）
        $positionAttr['is_men3'] = substr($positionArray, -16, 1) == 1 ? '门 3 开（后门）' : '门 3 关';
//            $positionAttr['is_men3'] = substr($positionArray, 16, 1) == 1 ? '门 3 开（后门）' : '门 3 关';
        //16 0：门 4 关；1：门 4 开（驾驶席门）
        $positionAttr['is_men4'] = substr($positionArray, -17, 1) == 1 ? '门 4 开（驾驶席门）' : '门 4 关';
//            $positionAttr['is_men4'] = substr($positionArray, 15, 1) == 1 ? '门 4 开（驾驶席门）' : '门 4 关';
        //17 0：门 5 关；1：门 5 开（自定义）
        $positionAttr['is_men5'] = substr($positionArray, -18, 1) == 1 ? '门 5 开（自定义）' : '门 5 关';
//            $positionAttr['is_men5'] = substr($positionArray, 14, 1) == 1 ? '门 5 开（自定义）' : '门 5 关';
        //18 0：未使用 GPS 卫星进行定位；1：使用 GPS 卫星进行定位
        $positionAttr['is_gps'] = substr($positionArray, -19, 1) == 1 ? '使用 GPS 卫星进行定位' : '未使用 GPS 卫星进行定位';
//            $positionAttr['is_gps'] = substr($positionArray, 13, 1) == 1 ? '使用 GPS 卫星进行定位' : '未使用 GPS 卫星进行定位';
        //19 0：未使用北斗卫星进行定位；1：使用北斗卫星进行定位
        $positionAttr['is_beidou'] = substr($positionArray, -20, 1) == 1 ? '使用北斗卫星进行定位' : '未使用北斗卫星进行定位';
//            $positionAttr['is_beidou'] = substr($positionArray, 12, 1) == 1 ? '使用北斗卫星进行定位' : '未使用北斗卫星进行定位';
        //20 0：未使用 GLONASS 卫星进行定位；1：使用 GLONASS 卫星进行定位
        $positionAttr['is_glonass'] = substr($positionArray, -21, 1) == 1 ?  '使用 GLONASS 卫星进行定位' : '未使用 GLONASS 卫星进行定位';
//            $positionAttr['is_glonass'] = substr($positionArray, 11, 1) == 1 ?  '使用 GLONASS 卫星进行定位' : '未使用 GLONASS 卫星进行定位';
        //21 0：未使用 Galileo 卫星进行定位；1：使用 Galileo 卫星进行定位
        $positionAttr['is_galileo'] = substr($positionArray, -22, 1) == 1 ? '使用 Galileo 卫星进行定位' : '未使用 Galileo 卫星进行定位';
//            $positionAttr['is_galileo'] = substr($positionArray, 10, 1) == 1 ? '使用 Galileo 卫星进行定位' : '未使用 Galileo 卫星进行定位';
        //22-31 保留

        return $positionAttr;
    }
// | 8 | 纬度 | DWORD | 以度为单位的纬度值乘以 10 的 6 次方，精确到百万分之一度 |
    /**
     * description   获取纬度
     * @param $data array  16进制数组
     * @param $index  数组索引
     * @param $type  返回字符类型 i整形 f浮点形
     * @return float|int   纬度
     */
    public function getLatitude($type = 'f') {
        $latitudeBytes = array_slice($this->mesageBody, 8, 4);
        $latitude = $this->jt808->bytesToInt($latitudeBytes);
        if ($type == 'f') {
            $number = $latitude / pow(10, 6);
        }
        if ($type == 'i') {
            $number = $latitude;
        }
        return $number;
    }
// | 12 | 经度 | DWORD | 以度为单位的经度值乘以 10 的 6 次方，精确到百万分之一度 |
    /**
     * description  获取经度
     * @param $data array  16进制数组
     * @param $index  数组索引
     * @param $type  返回字符类型 i整形 f浮点形
     * @return float|int  经度
     */
    public function getLongitude($type = 'f') {
        $longitudeBytes = array_slice($this->mesageBody, 12, 4);
        $longitude = $this->jt808->bytesToInt($longitudeBytes);
        if ($type == 'f') {
            $number = $longitude / pow(10, 6);
        }
        if ($type == 'i') {
            $number = $longitude;
        }
        return $number;
    }
// | 16 | 高程 | WORD | 海拔高度，单位为米（m） |
    /**
     * [getHeight 获取高度]
     * @author litaotxws@163.com
     * @DateTime 2020-04-30T14:12:30+0800
     * @param    [type]                   $data  [16进制数组]
     * @param    [type]                   $index [数组索引29]
     * @return   [type]                          [高度]
     */
    public function getHeight() {
        $heightBytes = array_slice($this->mesageBody, 16, 2);
        $height = $this->jt808->twoBytesToInteger($heightBytes);
        return $height;
    }
// | 18 | 速度 | WORD | 1/10km/h |
    /**
     * [getSpeed 获取速度]
     * @author litaotxws@163.com
     * @DateTime 2020-04-30T14:14:55+0800
     * @param    [type]                   $data  [16进制数组]
     * @param    [type]                   $index [数组索引31]
     * @return   [type]                          [速度]
     */
    public function getSpeed() {
        $speedBytes = array_slice($this->mesageBody, 18, 2);
        $speed = $this->jt808->twoBytesToInteger($speedBytes);
        return $speed;
    }
// | 20 | 方向 | WORD | 0-359，正北为 0，顺时针 |
    /**
     * [getDirection 获取方向]
     * @author litaotxws@163.com
     * @DateTime 2020-04-30T14:15:33+0800
     * @param    [type]                   $data  [16进制数组]
     * @param    [type]                   $index [数组索引33]
     * @return   [type]                          [方向]
     */
    public function getDirection() {
        $directionBytes = array_slice($this->mesageBody, 20, 2);
        $direction = $this->jt808->twoBytesToInteger($directionBytes);
        return $direction;
    }
// | 21 | 时间 | BCD[6] | YY-MM-DD-hh-mm-ss（GMT+8 时间，本标准中之后涉及的时间均采用此时区） |
    /**
     * description  获取日期时间
     * @return string   日期时间字符串
     */
    public function getDatetime(){
        $datetimeArray = array_slice($this->mesageBody, 22, 6);
        $datetimeStr = "20".$datetimeArray[0]."-".$datetimeArray[1]."-".$datetimeArray[2]." ".$datetimeArray[3].":".$datetimeArray[4].":".$datetimeArray[5];
        return $datetimeStr;
        $res = [];
        foreach ($datetimeArray as $k => $v) {
            $res[$k] = base_convert($v, 16, 10);
        }
        $datetime = $this->jt808->bcdToString($res);
        $datetimeStr = "20" . substr($datetime, 0, 2) . "-" . substr($datetime, 2, 2) . "-" . substr($datetime, 4, 2) . " " . substr($datetime, 6, 2) . ":" . substr($datetime, 8, 2) . ":" . substr($datetime, 10, 2);
        return $datetimeStr;
    }
}
?>